(function (line, support, global) {
    var dom = line.dom = line.dom || {};
    var attrMap = {
        "class":"className",
        "for":"htmlFor",
        tabindex:"tabIndex",
        readonly:"readOnly",
        maxlength:"maxLength",
        cellspacing:"cellSpacing",
        cellpadding:"cellPadding",
        rowspan:"rowSpan",
        colspan:"colSpan",
        usemap:"useMap",
        frameborder:"frameBorder",
        contenteditable:"contentEditable"
    };
    var attrHooks = {
        'href':{
            getter:function (element) {
                return element.getAttribute('href', 2);
            }
        },
        'html':{
            getter:function (element) {
                return dom.getHtml(element);
            },
            setter:function (element, html) {
                dom.setHtml(element, html);
            }
        },
        'text':{
            getter:function (element) {
                return dom.getText(element);
            },
            setter:function (element, text) {
                dom.setText(element, text);
            }
        },
        'value':{
            getter:function (element) {
                return dom.getValue(element);
            },
            setter:function (element, val) {
                dom.setValue(element, val);
            }
        }
    };

    function getClsPos(element, clsName) {
        return (' ' + element.className + ' ').indexOf(' ' + clsName + ' ');
    }

    line.extend(dom, {
        getAttribute:function (element, name) {
            var hook = attrHooks[name.toLowerCase()];
            if (hook && ('getter' in hook)) {
                return hook.getter(element);
            }
            name = attrMap[name] || name;
            if (name in element) {
                return element[name];
            } else {
                return element.getAttribute(element, name);
            }
        },
        setAttribute:function (element, name, value) {
            var hook = attrHooks[name.toLowerCase()];
            if (hook && ('setter' in hook)) {
                return hook.setter(element, name, value);
            }
            name = attrMap[name] || name;
            if (name in element) {
                //check/selected
                element[name] = value;
            } else {
                element.setAttribute(element, name, value);
            }
        },
        removeAttribute:function (element, name) {
            var hook = attrHooks[name.toLowerCase()];
            if (hook && ('remove' in hook)) {
                return hook.remove(element, name);
            }
            return element.removeAttribute(name);
        },
        addClass:function (element, clsName) {
            if (!this.hasClass(element, clsName)) {
                var curCls = element.className;
                element.className = curCls ? (curCls + ' ' + clsName) : clsName;
            }
        },
        removeClass:function (element, clsName) {
            var curCls = element.className,
                index = getClsPos(element, clsName);
            if (index > -1) {
                if (index == 0) {
                    element.className = curCls.replace(clsName + ' ', '');
                } else {
                    element.className = curCls.replace(' ' + clsName, '');
                }
            }
        },
        toggleClass:function (element, clsName) {
            if (this.hasClass(element, clsName)) {
                this.removeClass(element, clsName);
            } else {
                this.addClass(element, clsName);
            }
        },
        hasClass:function (element, clsName) {
            return getClsPos(element, clsName) > -1;
        },
        getHtml:function (element) {
            return element.innerHTML;
        },
        setHtml:function (element, html) {
            var specialElement = /<(?:object|embed|option|style)/i;
            if (!specialElement.test(element.tagName)) {
                element.innerHTML = html;
            } else {
                line.empty(element);
                element.appendChild(line.createDom(html));
            }
        },
        getText:(function () {
            if (support.innerText) {
                return function (element) {
                    return element.innerText || element.nodeValue;
                };
            } else {
                return function (element) {
                    return element.textContent;
                };
            }
        }()),
        setText:(function () {
            if (support.innerText) {
                return function (element, text) {
                    element.innerText = text;
                };
            } else {
                return function (element, text) {
                    element.textContent = text;
                };
            }
        }()),
        getValue:function (element) {
            return element.value;
        },
        setValue:function (element, val) {
            element.value = val;
        }
    });
})(line, line.support, window);